#include <iostream>
#include <vector>
#include <unistd.h>
#include <signal.h>

using std::cout;
using std::endl;

// #define block_signal 2
static std::vector<int> sigarr = {2};

// static std::vector<int> sigarr = {2, 3};

static void printf_pending(const sigset_t &pending) // 不想暴露给外部，加上static
{
    for (size_t signo = 31; signo > 0; --signo) // 拿到全部普通信号(打印是反着打印的，所以我们这里信号也要反正来，才保证最终结果顺序是正确的)
    {
        // 判断普通信号在不在pending信号集中
        if (sigismember(&pending, signo))
            cout << "1";
        else
            cout << "0";
    }
    cout << endl;
}

static void handler(const int signo)
{
    cout << signo << "信号被递达！" << endl;
}

int main()
{
    ////////捕捉信号
    for (const auto &signo : sigarr)
        signal(signo, handler);
    ////1、屏蔽指定信号
    sigset_t pending, block, oblock;
    // 1、1 初始化
    sigemptyset(&block);
    sigemptyset(&oblock);
    sigemptyset(&pending);

    // 1、2 添加要屏蔽的信号
    for (const auto &signo : sigarr)
        sigaddset(&block, signo);
    // 1、3 开始屏蔽,设置信号进内核（进程pcb的block位图）
    sigprocmask(SIG_SETMASK, &block, &oblock); // 将信号屏蔽字替换为block的，而oblock就存放原来的信号屏蔽字

    //// 2、遍历打印pending信号集
    int count = 10;
    while (1)
    {
        ////1、初始化 —— 清空pending位图，保证pending位图是全0
        sigemptyset(&pending);
        ////2、获取pending位图，不初始化也可以，因为这里是覆盖式的获取
        sigpending(&pending);
        ////3、打印pending位图
        printf_pending(pending);
        sleep(1);
        if (count-- == 0)
        {
            cout << "恢复信号屏蔽字" << endl;
            sigprocmask(SIG_SETMASK, &oblock, &block); // 这里oblock就是修改block位图之前的位图
            cout << "恢复信号屏蔽字" << endl;
        }
    }
    return 0;
}